package com.ler.yrmall.ware.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ler.yrmall.basic.Result;
import com.ler.yrmall.enums.ErrorCodeEnum;
import com.ler.yrmall.exception.BusinessException;
import com.ler.yrmall.product.api.ProductApi;
import com.ler.yrmall.product.dto.SkuDTO;
import com.ler.yrmall.ware.entity.PurchaseDetailEntity;
import com.ler.yrmall.ware.entity.WareSkuEntity;
import com.ler.yrmall.ware.form.PurchaseDetailForm;
import com.ler.yrmall.ware.mapper.PurchaseDetailMapper;
import com.ler.yrmall.ware.service.PurchaseDetailService;
import com.ler.yrmall.ware.service.WareSkuService;
import com.ler.yrmall.ware.vo.PurchaseDetailVO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author leron
 */
@Service
public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailMapper, PurchaseDetailEntity> implements PurchaseDetailService {

    @DubboReference
    private ProductApi productApi;

    @Resource
    private WareSkuService wareSkuService;

    @Override
    public IPage<PurchaseDetailVO> find(PurchaseDetailForm request) {
        Page<PurchaseDetailVO> page = this.baseMapper.find(request.getPage(),request);
        List<Long> skuIds = page.getRecords().stream().map(PurchaseDetailVO::getSkuId).collect(Collectors.toList());
        if (!skuIds.isEmpty()) {
            Result<List<SkuDTO>> skuResponse = productApi.listSkuByIds(skuIds);
            Assert.isTrue(skuResponse.isSuccess(),() -> new BusinessException(ErrorCodeEnum.SKU_FIND_ERROR));
            Map<Long, SkuDTO> skuMap = skuResponse.getData().stream().collect(Collectors.toMap(SkuDTO::getId, Function.identity(), (a, b) -> a));
            page.getRecords().forEach(item -> item.setSkuName(Optional.ofNullable(skuMap.get(item.getSkuId())).map(SkuDTO::getName).orElse("")));
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PurchaseDetailEntity request) {
        PurchaseDetailEntity byId = this.getById(request.getId());
        if (PurchaseDetailEntity.PurchaseDetailStatus.FINISH.getCode().equals(byId.getStatus())) {
            throw new BusinessException(ErrorCodeEnum.PURCHASE_FINISH_ERROR);
        }

        if (PurchaseDetailEntity.PurchaseDetailStatus.FINISH.getCode().equals(request.getStatus())) {
            request.setFinishTime(LocalDateTime.now());
            // 商品入库
            WareSkuEntity ws = wareSkuService.getOne(Wrappers.<WareSkuEntity>lambdaQuery()
                    .eq(WareSkuEntity::getWareId, byId.getWareId())
                    .eq(WareSkuEntity::getSkuId, byId.getSkuId()));
            if (ws == null) {
                ws = new WareSkuEntity();
                ws.setSkuId(byId.getSkuId());
                ws.setStockLocked(0);
                ws.setStock(byId.getSkuNum());
                ws.setWareId(byId.getWareId());
                wareSkuService.save(ws);
            } else {
                wareSkuService.increment(ws.getId(),byId.getSkuNum());
            }
        }
        this.updateById(request);
    }
}